﻿namespace MDXStudio
{
    using MDXParser;
    using Microsoft.AnalysisServices;
    using Microsoft.AnalysisServices.AdomdClient;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows.Forms;

    internal class Query
    {
        private ToolStripButton[] ButtonsToEnable;
        private AdomdCommand Command;
        private VirtualGrid DisplayGrid;
        private bool m_Busy;
        private Timer m_Timer;
        private string m_Version;
        private MDXStudio.MessageLog MessageLog;
        private MDXStudio.PerfStats PerfStats;
        private MDXStudio.ResultsWindow ResultsWindow;
        private string ServerName;
        private BackgroundWorker Worker;

        public Query(MDXStudio.MessageLog inMessageLog, Timer t, MDXStudio.PerfStats inPerfStats, ToolStripButton[] inButtonsToEnable)
        {
            this.m_Timer = t;
            this.ButtonsToEnable = inButtonsToEnable;
            this.MessageLog = inMessageLog;
            this.PerfStats = inPerfStats;
            this.Worker = new BackgroundWorker();
            this.Worker.WorkerReportsProgress = false;
            this.Worker.WorkerSupportsCancellation = true;
            this.Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.OnWorkCompleted);
            this.Worker.DoWork += new DoWorkEventHandler(this.OnDoWork);
        }

        public void Cancel()
        {
            try
            {
                this.Command.Cancel();
            }
            catch (Exception exception)
            {
                this.MessageLog.WriteErrorMessage(exception.Message);
            }
            finally
            {
                this.Worker.CancelAsync();
            }
        }

        private void OnDoWork(object sender, DoWorkEventArgs e)
        {
            if (this.ServerName != null)
            {
                this.PerfStats.Start(this.ServerName, this.m_Version);
            }
            BackgroundWorker worker = sender as BackgroundWorker;
            CellSet set = (e.Argument as AdomdCommand).ExecuteCellSet();
            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                e.Result = set;
            }
        }

        private void OnWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.m_Timer.Stop();
            this.m_Timer.Enabled = false;
            if (this.ServerName != null)
            {
                this.PerfStats.Finish();
            }
            this.m_Busy = false;
            if (e.Error != null)
            {
                this.MessageLog.WriteErrorMessage(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                this.MessageLog.WriteErrorMessage("Operation was cancelled");
            }
            else
            {
                if (this.DisplayGrid != null)
                {
                    this.MessageLog.WriteMessage("Execution complete");
                }
                if (this.ServerName != null)
                {
                    this.PerfStats.Display();
                }
                CellSet result = e.Result as CellSet;
                if (this.DisplayGrid != null)
                {
                    this.DisplayGrid.DrawCellSetInGrid(result, this.MessageLog, false);
                }
            }
            if (this.ResultsWindow != null)
            {
                this.ResultsWindow.InitToobarMenus();
            }
            foreach (ToolStripButton button in this.ButtonsToEnable)
            {
                button.Enabled = true;
            }
        }

        public void RunAndDisplay(AdomdConnection Connection, Server AmoServer, string inServerName, string QueryText, List<MDXParameter> Params, VirtualGrid inDisplayGrid, MDXStudio.ResultsWindow inResultsWindow)
        {
            try
            {
                this.m_Busy = true;
                foreach (ToolStripButton button in this.ButtonsToEnable)
                {
                    button.Enabled = false;
                }
                this.ServerName = inServerName;
                this.DisplayGrid = inDisplayGrid;
                this.ResultsWindow = inResultsWindow;
                this.m_Version = "2008";
                if (Connection.ServerVersion.StartsWith("9."))
                {
                    this.m_Version = "2005";
                }
                this.Command = Connection.CreateCommand();
                this.Command.CommandText = QueryText;
                if (Params != null)
                {
                    foreach (MDXParameter parameter in Params)
                    {
                        this.Command.Parameters.Add(parameter.Name, parameter.Value);
                    }
                }
                this.m_Timer.Enabled = true;
                this.m_Timer.Start();
                if (this.DisplayGrid != null)
                {
                    this.MessageLog.WriteMessage("Executing the query ...");
                }
                this.Worker.RunWorkerAsync(this.Command);
            }
            catch (Exception exception)
            {
                this.MessageLog.WriteErrorMessage(exception.Message);
                this.m_Busy = false;
            }
        }

        public void WaitForCompletion()
        {
            while (this.IsBusy)
            {
                Application.DoEvents();
            }
        }

        internal bool IsBusy
        {
            get
            {
                return this.m_Busy;
            }
        }
    }
}

